#include "tree_match.hpp"

optional<sa> x_eq_a(CFGvertex *n) {
	sa ret;
	
	if (TRY_TYPE(box*, b, n))
	if (TRY_TYPE(assignment*, a, b->payload))
	if (TRY_TYPE(variable*, v, a->dest)) {
		ret.x = v;
		ret.a = a->rhs;
		return ret;
	}

	return optional<sa>();
}

optional<aa> Aa1_eq_a2(CFGvertex *n) {
	aa ret;
	
	if (TRY_TYPE(box*, b, n))
	if (TRY_TYPE(assignment*, a, b->payload))
	if (TRY_TYPE(array_element*, v, a->dest)) {
		ret.A = v;
		ret.a1 = v->index;
		ret.a2 = a->rhs;
		return ret;
	}
	
	return optional<aa>();	
}

optional<rst> read_x(CFGvertex *n) {
	rst ret;
	
	if (TRY_TYPE(box*, b, n))
	if (TRY_TYPE(s_read*, r, b->payload))
	if (TRY_TYPE(variable*, v, r->dest)) {
		ret.x = v;
		return ret;
	}
	
	return optional<rst>();
}

optional<rsta> read_Aa1(CFGvertex *n) {
	rsta ret;
	
	if (TRY_TYPE(box*, b, n))
	if (TRY_TYPE(s_read*, r, b->payload))
	if (TRY_TYPE(array_element*, ae, r->dest)) {
		ret.A = ae;
		ret.a1 = ae->index;
		return ret;
	}
	
	return optional<rsta>();
}

optional<wst> write_a(CFGvertex *n) {
	wst ret;
	
	if (TRY_TYPE(box*, b, n))
	if (TRY_TYPE(s_write*, w, b->payload)) {
		ret.a = w->arg;
		return ret;
	}
	
	return optional<wst>();	
}

optional<ss> skip(CFGvertex *n) {
	ss ret;
	
	if (TRY_TYPE(box*, b, n))
	if (TRY_TYPE(s_skip*, s, b->payload)) {
		return ret;
	}
	
	return optional<ss>();	
}

optional<be> b(CFGvertex *n) {
	be ret;
	
	if (TRY_TYPE(diamond*, d, n)) {
		ret.b = d->condition;
		return ret;
	}
	
	return optional<be>();	
}

optional<pr> pred(CFGvertex *n) {
	pr ret;
	
	if (TRY_TYPE(box*, d, n)) 
	if (TRY_TYPE(bexp*, b, d->payload)) {
		ret.predicate = b;
		return ret;
	}
	
	return optional<pr>();	
}
